#ifndef HUFFMAN
#define HUFFMAN

#include "bf.h"

typedef struct huff_node_struct {
  int w;           // le poids
  int c;           // le caractere
  int gdbh_index;  // index dans gdbh
  struct huff_node_struct *father;  
  struct huff_node_struct *left;
  struct huff_node_struct *right;
} *huff_node;

typedef struct huff_tree_struct {
  huff_node root;       // la racine
  huff_node special;    // le pere de diese
  huff_node chars[256]; // hash char -> huff_node
  huff_node gdbh[512];  // l'ordre gdbh
  int count;            // nobre de symboles
} huff_tree;

typedef struct huff_code_struct {
  int length;  // la longueur de ce code
  int bits;    // et le code
} *huff_code;

extern huff_tree thetree;

void      huff_code_tostring (huff_code this);

huff_node huff_node_new ();
void      huff_node_init (huff_node this, int w, int c, huff_node f, huff_node l, huff_node r, int i);
void      huff_node_tostring (huff_node this);
void      huff_node_exchange (huff_node q, huff_node r);
int       huff_node_isgdbh (huff_node this);
huff_node huff_node_eob (huff_node this);
void      huff_node_get_code (huff_node this, huff_code res);
int       huff_node_isspecial (huff_node this);
int       huff_node_isleaf (huff_node this);

void      huff_tree_init (int c);
void      huff_tree_tostring ();
void      huff_tree_update (huff_node q);
void      huff_tree_modify (int c);


int huff_getcode (int c, huff_code res);
void huff_putcode (bf_stream bf, huff_code c);
void huff_special_code (huff_code res);

#endif
